package com.autumn.platform.core.xml;

import java.io.IOException;
import java.util.Properties;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.PropertiesLoaderUtils;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import com.autumn.platform.core.Utils;

public class PropertiesEntityResolver implements EntityResolver, InitializingBean {

    private static final String DEFAULT_NAMESPACE_PROPERTIES_FILE_PATTERN = "classpath*:/META-INF/autumn-namespaces*.properties";

    private String namespacePropertiesFilePattern = DEFAULT_NAMESPACE_PROPERTIES_FILE_PATTERN;

    private Properties properties = null;

    public PropertiesEntityResolver() {}

    public PropertiesEntityResolver(String namespacePropertiesFilePattern) {
        this.namespacePropertiesFilePattern = namespacePropertiesFilePattern;
    }

    @Override
    public InputSource resolveEntity(String publicId, String systemId) throws SAXException, IOException {
        if (Utils.isBlank(systemId)) {
            return null;
        }
        String resourceLocation = properties.getProperty(systemId);
        if (resourceLocation != null) {
            return resolveInputSource(publicId, systemId, new ClassPathResource(resourceLocation));
        }
        return null;
    }

    private InputSource resolveInputSource(String publicId, String systemId, Resource resource) throws IOException {
        InputSource source = new InputSource(resource.getInputStream());
        source.setPublicId(publicId);
        source.setSystemId(systemId);
        return source;
    }

    @Override
    public void afterPropertiesSet() throws Exception {
        if (null == this.namespacePropertiesFilePattern) {
            throw new IllegalStateException("the namespace-properties-file-pattern is empty.");
        }
        if (null == properties) {
            synchronized (this) {
                if (null == properties) {
                    Properties p = new Properties();
                    ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();
                    Resource[] resources = resolver.getResources(namespacePropertiesFilePattern);
                    if (null != resources) {
                        for (Resource resource : resources) {
                            PropertiesLoaderUtils.fillProperties(p, resource);
                        }
                    }
                    properties = p;
                }
            }
        }
    }
}
